package com.zjdiepu.www.service.hzicbc.impl;

import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.diepu.www.client.hzicbc.proxy.enums.ReturnCodePrefixType;
import com.diepu.www.client.hzicbc.proxy.request.applyCredit.ApplyCreditRequest;
import com.diepu.www.client.hzicbc.proxy.request.applyDivi.ApplyDiviRequest;
import com.diepu.www.client.hzicbc.proxy.request.applyDiviGeneral.ApplyDiviGeneralRequest;
import com.diepu.www.client.hzicbc.proxy.request.applyStatus.ApplyStatusRequest;
import com.diepu.www.client.hzicbc.proxy.request.creditCardApply.CreditCardApplyRequest;
import com.diepu.www.client.hzicbc.proxy.request.creditStatus.CreditStatusRequest;
import com.diepu.www.client.hzicbc.proxy.request.fileDownload.FileDownloadRequest;
import com.diepu.www.client.hzicbc.proxy.request.multimediaupload.MultimediauploadRequest;
import com.diepu.www.client.hzicbc.proxy.request.qryMargin.QryMarginRequest;
import com.diepu.www.client.hzicbc.proxy.response.PublicResponse;
import com.diepu.www.client.hzicbc.proxy.response.applyStatus.ApplyStatusInfo;
import com.diepu.www.client.hzicbc.proxy.response.creditStatus.CreditStatusInfo;
import com.diepu.www.client.hzicbc.proxy.response.qryMargin.AccountInfo;
import com.icbc.api.core.ApiClient;
import com.icbc.api.core.ApiException;
import com.icbc.api.core.ApiRequest;
import com.icbc.api.core.ApiResponse;
import com.zjdiepu.www.config.ClientConfig;
import com.zjdiepu.www.consts.HzicbcService;
import com.zjdiepu.www.security.exception.BaseRunTimeException;
import com.zjdiepu.www.security.exception.ParamException;
import com.zjdiepu.www.security.exception.ProgramException;
import com.zjdiepu.www.security.exception.SystemException;
import com.zjdiepu.www.security.server.core.Partners;
import com.zjdiepu.www.service.base.ICommonLogService;
import com.zjdiepu.www.service.hzicbc.IHzicbcService;

/**
 * 杭州工商银行接口服务
 * @author xiongxiaotun
 *
 */
@Service
public class HzicbcServiceImpl implements IHzicbcService {
	private static Logger logger = LoggerFactory.getLogger(HzicbcServiceImpl.class);
	private Partners partner = Partners.HZ_ICBC;
	
	@Autowired
	private ApiClient hzicbcApiClient;
	@Autowired
	private ICommonLogService commonLogService;

	@Override
	public ApiResponse applyCredit(ApplyCreditRequest request, String appId) throws Exception {
		ApiRequest apiRequest = new ApiRequest(ClientConfig.getPartnerGateWay(partner), HzicbcService.APPLY_CREDIT_APINAME, appId);
		apiRequest.setRequestField("pub", JSON.toJSONString(request.getPub()));
		apiRequest.setRequestField("req",JSON.toJSONString(request.getReq()));
		ApiResponse ar = null;
		String exceptionDes = null;
		boolean statusEvent = false;
		try {
			ar = hzicbcApiClient.execute(apiRequest);
			statusEvent = true;
			return ar; 
		} catch(Exception e){
			exceptionDes = e.getCause().toString();
			throw e;
		} finally {
			commonLogService.insertRequestLog(request, ar, exceptionDes, HzicbcService.APPLY_CREDIT_APINAME, statusEvent);
		}
		
	}

	@Override
	public boolean applyDivi(ApplyDiviRequest request, String appId) {
		ApiRequest apiRequest = new ApiRequest(ClientConfig.getPartnerGateWay(partner), HzicbcService.APPLY_DIVI_APINAME, appId);
		apiRequest.setRequestField("pub", JSON.toJSONString(request.getPub()));
		apiRequest.setRequestField("req",JSON.toJSONString(request.getReq()));
		ApiResponse ar = null;
		String exceptionDes = null;
		boolean statusEvent = false;
		try {
			ar = hzicbcApiClient.execute(apiRequest);
			statusEvent = true;
			return check(ar);
		} catch (ApiException e) {
			logger.error("HzicbcServiceImpl.applyDivi happened exception when request hzicbc. request : {}.", JSON.toJSONString(request), e);
			exceptionDes = "请求工行发生ApiException异常";
			return false;
		} catch(BaseRunTimeException e){
			exceptionDes = e.getErrorMsg();
			throw e;
		} catch(Exception e){
			exceptionDes = e.getCause().toString();
			throw e;
		} finally {
			commonLogService.insertRequestLog(request, ar, exceptionDes, HzicbcService.APPLY_DIVI_APINAME, statusEvent);
		}
	}

	@Override
	public ApplyStatusInfo applyDiviStatus(ApplyStatusRequest request, String appId) {
		ApiRequest apiRequest = new ApiRequest(ClientConfig.getPartnerGateWay(partner), HzicbcService.APPLY_STATUS_APINAME,  appId);
		apiRequest.setRequestField("pub", JSON.toJSONString(request.getPub()));
		ApiResponse ar = null;
		String exceptionDes = null;
		boolean statusEvent = false;
		try {
			ar = hzicbcApiClient.execute(apiRequest);
			statusEvent = true;
			if(check(ar)) {
				Map<Object, Object> ans = ar.getMap("ans");
				return JSON.parseObject(JSON.toJSONString(ans), ApplyStatusInfo.class);
			}
			return null;
		} catch (ApiException e) {
			logger.error("HzicbcServiceImpl.applyStatus happened exception when request hzicbc. request : {}.", JSON.toJSONString(request), e);
			exceptionDes = "请求工行发生ApiException异常";
			return null;
		} catch(BaseRunTimeException e){
			exceptionDes = e.getErrorMsg();
			throw e;
		} catch(Exception e){
			exceptionDes = e.getCause().toString();
			throw e;
		} finally {
			commonLogService.insertRequestLog(request, ar, exceptionDes, HzicbcService.APPLY_STATUS_APINAME, statusEvent);
		}
	}

	@Override
	public boolean fileDownload(FileDownloadRequest request, String remoteFileName, String localPath, String appId) {
		ApiRequest apiRequest = new ApiRequest(ClientConfig.getPartnerGateWay(partner), HzicbcService.FILE_DOWNLOAD_APINAME,  appId);
		apiRequest.setRequestField("pub", JSON.toJSONString(request.getPub()));
		apiRequest.setRequestField("req",JSON.toJSONString(request.getReq()));
		ApiResponse ar = null;
		String exceptionDes = null;
		boolean statusEvent = false;
		try {
			hzicbcApiClient.doDownload(apiRequest, remoteFileName, localPath);
			statusEvent = true;
			return true;
		} catch (ApiException e) {
			logger.error("HzicbcServiceImpl.fileDownload happened exception when request hzicbc. request : {}.", JSON.toJSONString(request), e);
			exceptionDes = "请求工行发生ApiException异常";
			return false;
		} catch(BaseRunTimeException e){
			exceptionDes = e.getErrorMsg();
			throw e;
		} catch(Exception e){
			exceptionDes = e.getCause().toString();
			throw e;
		} finally {
			commonLogService.insertRequestLog(request, ar, exceptionDes, HzicbcService.FILE_DOWNLOAD_APINAME, statusEvent);
		}
	}

	@Override
	public boolean applyDiviGeneral(ApplyDiviGeneralRequest request, String appId) {
		ApiRequest apiRequest = new ApiRequest(ClientConfig.getPartnerGateWay(partner), HzicbcService.APPLY_DIVI_GENERAL_APINAME,  appId);
		apiRequest.setRequestField("pub", JSON.toJSONString(request.getPub()));
		apiRequest.setRequestField("req",JSON.toJSONString(request.getReq()));
		ApiResponse ar = null;
		String exceptionDes = null;
		boolean statusEvent = false;
		try {
			ar = hzicbcApiClient.execute(apiRequest);
			statusEvent = true;
			return check(ar);
		} catch (ApiException e) {
			logger.error("HzicbcServiceImpl.applyDiviGeneral happened exception when request hzicbc. request : {}.", JSON.toJSONString(request), e);
			exceptionDes = "请求工行发生ApiException异常";
			return false;
		}  catch(BaseRunTimeException e){
			exceptionDes = e.getErrorMsg();
			throw e;
		} catch(Exception e){
			exceptionDes = e.getCause().toString();
			throw e;
		} finally {
			commonLogService.insertRequestLog(request, ar, exceptionDes, HzicbcService.APPLY_DIVI_GENERAL_APINAME, statusEvent);
		}
	}
	
	@Override
	public boolean multiMediaUpload(MultimediauploadRequest request, String appId) {
		ApiRequest apiRequest = new ApiRequest(ClientConfig.getPartnerGateWay(partner), HzicbcService.MULTI_MEDIA_UPLOAD_APINAME, appId);
		apiRequest.setRequestField("pub", JSON.toJSONString(request.getPub()));
		apiRequest.setRequestField("req",JSON.toJSONString(request.getReq()));
		ApiResponse ar = null;
		String exceptionDes = null;
		boolean statusEvent = false;
		try {
			ar = hzicbcApiClient.execute(apiRequest);
			statusEvent = true;
			return check(ar);
		} catch (ApiException e) {
			logger.error("HzicbcServiceImpl.multiMediaUpload happened exception when request hzicbc. request : {}.", JSON.toJSONString(request), e);
			exceptionDes = "请求工行业务多媒体资料补充接口发生ApiException异常";
			return false;
		}  catch(BaseRunTimeException e){
			exceptionDes = e.getErrorMsg();
			throw e;
		} catch(Exception e){
			exceptionDes = e.getCause().toString();
			throw e;
		} finally {
			commonLogService.insertRequestLog(request, ar, exceptionDes, HzicbcService.MULTI_MEDIA_UPLOAD_APINAME, statusEvent);
		}
	}

	@Override
	public ApiResponse creditCardApply(CreditCardApplyRequest request, String appId) {
		ApiRequest apiRequest = new ApiRequest(ClientConfig.getPartnerGateWay(partner), HzicbcService.CREDIT_CARD_APPLY_APINAME,  appId);
		apiRequest.setRequestField("pub", JSON.toJSONString(request.getPub()));
		apiRequest.setRequestField("req",JSON.toJSONString(request.getReq()));
		ApiResponse ar = null;
		String exceptionDes = null;
		boolean statusEvent = false;
		try {
			ar = hzicbcApiClient.execute(apiRequest);
			statusEvent = true;
			return ar;
		} catch (ApiException e) {
			logger.error("HzicbcServiceImpl.creditCardApply happened exception when request hzicbc. request : {}.", JSON.toJSONString(request), e);
			exceptionDes = "请求工行发生ApiException异常";
			return null;
		} catch(Exception e){
			exceptionDes = e.getCause().toString();
			throw e;
		} finally {
			commonLogService.insertRequestLog(request, ar, exceptionDes, HzicbcService.CREDIT_CARD_APPLY_APINAME, statusEvent);
		}
	}

	@Override
	public AccountInfo qryMargin(QryMarginRequest request, String appId) {
		ApiRequest apiRequest = new ApiRequest(ClientConfig.getPartnerGateWay(partner), HzicbcService.QRY_MARGIN_APINAME,  appId);
		apiRequest.setRequestField("pub", JSON.toJSONString(request.getPub()));
		ApiResponse ar = null;
		String exceptionDes = null;
		boolean statusEvent = false;
		try {
			ar = hzicbcApiClient.execute(apiRequest);
			statusEvent = true;
			if(check(ar)) {
				Map<Object, Object> ans = ar.getMap("ans");
				return JSON.parseObject(JSON.toJSONString(ans), AccountInfo.class);
			}
		} catch (ApiException e) {
			logger.error("HzicbcServiceImpl.creditCardApply happened exception when request hzicbc. request : {}.", JSON.toJSONString(request), e);
			exceptionDes = "请求工行发生ApiException异常";
			return null;
		} catch(Exception e){
			exceptionDes = e.getCause().toString();
			throw e;
		} finally {
			commonLogService.insertRequestLog(request, ar, exceptionDes, HzicbcService.QRY_MARGIN_APINAME, statusEvent);
		}
		return null;
	}

	@Override
	public CreditStatusInfo applyCreditStatus(CreditStatusRequest request, String appId) {
		ApiRequest apiRequest = new ApiRequest(ClientConfig.getPartnerGateWay(partner), HzicbcService.APPLY_CREDIT_STATUS_APINAME, appId);
		apiRequest.setRequestField("pub", JSON.toJSONString(request.getPub()));
		ApiResponse ar = null;
		String exceptionDes = null;
		boolean statusEvent = false;
		try {
			ar = hzicbcApiClient.execute(apiRequest);
			statusEvent = true;
			if(check(ar)) {
				Map<Object, Object> ans = ar.getMap("ans");
				return JSON.parseObject(JSON.toJSONString(ans), CreditStatusInfo.class);
			}
		} catch (ApiException e) {
			logger.error("HzicbcServiceImpl.applyCreditStatus happened exception when request hzicbc. request : {}.", JSON.toJSONString(request), e);
			exceptionDes = "请求工行发生ApiException异常";
			return null;
		} catch(Exception e){
			exceptionDes = e.getCause().toString();
			throw e;
		} finally {
			commonLogService.insertRequestLog(request, ar, exceptionDes, HzicbcService.APPLY_CREDIT_STATUS_APINAME, statusEvent);
		}
		return null;
	}
	
//	===================================辅助方法=============================
	/**
	 * 结果解析
	 * @param ar
	 * @return
	 */
	private boolean check(ApiResponse ar) {
		Map<Object, Object> pub = ar.getMap("pub");
		if(null != pub) {
			PublicResponse publicResponse = JSON.parseObject(JSON.toJSONString(pub), PublicResponse.class);
			if(null == publicResponse) {
				throw new SystemException("30001","联调环境错误");
			}
			String retcode = publicResponse.getRetcode();
			String retmsg = publicResponse.getRetmsg();
			if(StringUtils.isBlank(retcode)) {
				throw new SystemException("30002","联调环境错误");
			}
			if(retcode.startsWith(ReturnCodePrefixType.SUCCESS.getCode())){
				return true;
			} else if(retcode.startsWith(ReturnCodePrefixType.FAIL_PARAM.getCode())){
				logger.error("check response object. retcode is {}, retmsg is {}.", retcode, retmsg);
				throw new ParamException(retcode, retmsg);
			} else if(retcode.startsWith(ReturnCodePrefixType.FAIL_WDYMXQDWJ.getCode())){
				logger.error("check response object. retcode is {}, retmsg is {}.", retcode, retmsg);
				throw new ProgramException(retcode, retmsg);
			} else if(retcode.startsWith(ReturnCodePrefixType.FAIL_YQCJQDWJ.getCode())){
				logger.error("check response object. retcode is {}, retmsg is {}.", retcode, retmsg);
				throw new SystemException(retcode, retmsg);
			}
			throw new SystemException(retcode, retmsg);
		}
		throw new SystemException("30002","联调环境错误");
	}


}
